//
//  ReachedBottomViewController.swift
//  iOS-RxSwift-Tutorials_Example
//
//  Created by mengru.tian on 2020/9/24.
//  Copyright © 2020 CocoaPods. All rights reserved.
//

import UIKit
import RxSwift
import RxCocoa

extension Reactive where Base: UIScrollView  {
     
    //视图滚到底部检测序列
    var reachedBottom: Signal<()> {
        return contentOffset.asDriver()
            .flatMap { [weak base] contentOffset -> Signal<()> in
                guard let scrollView = base else {
                    return Signal.empty()
                }
                 
                //可视区域高度
                let visibleHeight = scrollView.frame.height - scrollView.contentInset.top
                    - scrollView.contentInset.bottom
                //滚动条最大位置
                let threshold = max(0.0, scrollView.contentSize.height - visibleHeight)
                //如果当前位置超出最大位置则发出一个事件
                let y = contentOffset.y + scrollView.contentInset.top
                return y > threshold ? Signal.just(()) : Signal.empty()
        }
    }
}

class ReachedBottomViewController: UIViewController {
    
    var tableView: UITableView!
    //表格数据序列
    let tableData = BehaviorRelay<[String]>(value: [])
     
    let disposeBag = DisposeBag()
    
    //当前是否正在加载序列
    var isLoading = BehaviorRelay<Bool>(value: false)
    //表格底部用来提示数据加载的视图
    var loadMoreView:UIView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        title = "61.监听滚动条滚动到底部的行为：reachedBottom"
        view.backgroundColor = .white
        
        test()
    }
    
    func test() {
        //创建表格视图
        self.tableView = UITableView(frame: self.view.frame, style:.plain)
        //创建一个重用的单元格
        self.tableView!.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
        self.view.addSubview(self.tableView!)
        //初始化表格尾部的上拉刷新视图
        self.setupInfiniteScrollingView()
        //单元格数据的绑定
        self.tableData.asDriver()
            .drive(tableView.rx.items) { (tableView, row, element) in
                let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")!
                cell.textLabel?.text = "\(row+1)、\(element)"
                return cell
            }
            .disposed(by: disposeBag)
        
        //表格尾部的上拉加载视图显示绑定
        self.isLoading.asDriver()
            .drive(onNext: {
                if $0 {
                    self.tableView.tableFooterView = self.loadMoreView
                }else{
                    self.tableView.tableFooterView = nil
                }
            })
            .disposed(by: disposeBag)
         
        //上拉加载数据
        self.tableView.rx.reachedBottom.asObservable()
            .startWith(()) //初始化完毕时会自动加载一次数据
            .flatMapFirst(getRandomResult) //防止重复加载
            .subscribe(onNext: { [weak self] items in
                if let tableData = self?.tableData {
                    tableData.accept(tableData.value + items )
                }
                self?.isLoading.accept(false)
            })
            .disposed(by: disposeBag)
    }
    //获取随机数据
    func getRandomResult() -> Driver<[String]> {
        print("正在请求数据......")
        //随机生成20条数据
        let items = Array(0..<20).map{ _ in "随机条目\(arc4random())"}
        let observable = Observable.just(items)
        return observable
            .delay(2, scheduler: MainScheduler.instance)
            .asDriver(onErrorDriveWith: Driver.empty())
    }
    
    //上拉加载视图
    private func setupInfiniteScrollingView() {
        self.loadMoreView = UIView(frame: CGRect(x:0, y:self.tableView.contentSize.height,
                                    width:self.tableView.bounds.size.width, height:40))
        self.loadMoreView!.autoresizingMask = .flexibleWidth
         
        //添加中间的环形进度条
        let activityViewIndicator = UIActivityIndicatorView(activityIndicatorStyle: .white)
        activityViewIndicator.color = .darkGray
        let indicatorX = self.loadMoreView!.frame.size.width/2
            - activityViewIndicator.frame.width/2
        let indicatorY = self.loadMoreView!.frame.size.height/2
            - activityViewIndicator.frame.height/2
        activityViewIndicator.frame = CGRect(x:indicatorX, y:indicatorY,
                                             width:activityViewIndicator.frame.width,
                                             height:activityViewIndicator.frame.height)
        activityViewIndicator.startAnimating()
        self.loadMoreView!.addSubview(activityViewIndicator)
    }

}
